﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using BaseMethods;
using Pattern.Common;
using Pattern.Model;

namespace Pattern.Logic
{
    public static class Algorithm
    {
        public static Tuple<double, int> Proceed(List<Sample>[] samples, int valid, double k, int numberOfClasses)
        {
            var learning = new List<Sample>();
            var dict = new Dictionary<int, Dictionary<int, double>>();
            List<Sample> validating = null;

            // podział sampli
            for (int i = 0; i < samples.Length; i++)
            {
                if (i == valid)
                {
                    validating = samples[i];
                }
                else
                {
                    learning = learning.Concat(samples[i]).ToList();
                }
            }

            var result = new int[validating.Count, 2];
          //  var aposteriori = new double[validating.Count];
            var trafione = new bool[validating.Count];
            for (int i = 0; i < validating.Count; i++) // dla kazdego elementu ciągu
            {
                var val = validating[i];
                var mian = 0.0;
                var licz = 0.0;
              //  var aposterSum = new double[numberOfClasses];
                foreach (var ler in learning) // dla kazdego elementu ciagu uczacego
                {
                    var ker = Kernel.Epanechnikov((val - ler).EuclidianNorm() / k);
                    licz += ker * (ler.Class);
                    mian += ker;

                    // a poster 
          
                //        aposterSum[ler.Class-1] += ker;
                   
                    // a poster
                }
               
                var pred = (int)Math.Round(licz / mian);

                result[i, 0] = val.Class;
                result[i, 1] = pred;
                trafione[i] = val.Class == pred;

                //var qi = new double[numberOfClasses];
                //var sum = 0.0;
                //for (int j = 0; j < numberOfClasses; j++)
                //{
                //    var q = learning.Count(sample => sample.Class == j + 1);
                //    aposterSum[j] = aposterSum[j] / k /q;
                //    qi[j] = q/(double)learning.Count;
                //    sum += aposterSum[j]*qi[j];
                //}

                //var propWar = (qi[val.Class - 1]*aposterSum[val.Class - 1])/sum;
                //aposteriori[i] = propWar;
            }
           // var labMse = result.MseLabels(numberOfClasses,aposteriori);
            var mse = result.Mse();
         //   return new Tuple<double, double>(mse, labMse);
            return new Tuple<double,int>(mse,trafione.Count(b => b));
        }


    }
}
